home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Almathera Ten Pack 3: CDPD 3
/
Almathera Ten on Ten - Disc 3: CDPD3.iso
/
scope
/
001-025
/
scopedisk8
/
hunker
/
hunker.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-03-18
|
10KB
|
549 lines
#include <stdio.h>
#include <libraries/dosextens.h>
#include <functions.h>
#include "hunk.h"
#include <exec/types.h>
#define DC SET_UNCHANGED /* dont change flag */
int first = 0, last = 1, current, listsize;
struct FileHandle *fd;
ULONG codemem=DC, datamem=DC, bssmem=DC, memtype(), *changelist = NULL;
BOOL verbose = FALSE;
main(argc, argv)
int argc;
char **argv;
{
int i = 2;
if (argc < 3)
{
show_usage(argv[0]);
}
while (i < argc)
{
if (argv[i][0] == '-')
{
if (argv[i][1] == VERBOSE_FLAG) {
verbose = TRUE;
}
}
else if ((argv[i][1] != '=') && (argv[i][0] != '-'))
{
show_usage(argv[0]);
exit(0);
}
else {
set_mem_flags(argv[i]);
}
i++;
}
if ((fd = Open(argv[1],MODE_OLDFILE))==NULL)
{
printf("Sorry, file: %s not found\n",argv[1]);
exit(10);
}
processfile();
fixhunk();
Exit();
}
/***********************************************************************
*
* ROUTINE: memtype
*
* IMPORTS: char type; character after '=' in CLI arg
*
* RETURNS: ULONG memtype; memory specification long word
*
* DESCRIPTION: returns the mask for the type of memory specified by
* the character after the '=' in a CLI argument
*
***********************************************************************/
ULONG memtype(type)
char type;
{
ULONG settype;
switch (type)
{
case SPEC_CHIP:
settype = SET_CHIP;
break;
case SPEC_FAST:
settype = SET_FAST;
break;
case SPEC_EITHER:
settype = SET_EITHER;
break;
default:
settype = SET_UNCHANGED;
}
return(settype);
}
/***********************************************************************
*
* ROUTINE: processfile
*
* IMPORTS: none
*
* RETURNS: none
*
* DESCRIPTION: reads through the file until the last hunk has bee processed
*
***********************************************************************/
processfile()
{
ULONG hunk, readlong();
while (first <= last)
{
hunk = (readlong());
if (verbose) {
printf("Hunk type %x\n", hunk);
}
processhunk(hunk);
}
}
/***********************************************************************
*
* ROUTINE: readlong
*
* IMPORTS: NONE
*
* RETURNS: ULONG data; long word read from the file
*
* DESCRIPTION: reads the next long word in the file
*
***********************************************************************/
ULONG readlong()
{
ULONG hunk[2];
int bytes;
if ((bytes = Read(fd, hunk, sizeof(ULONG))) < sizeof(ULONG))
{
printf("could not read full long word\n");
Exit(0);
}
return(hunk[0]);
}
/***********************************************************************
*
* ROUTINE: processhunk
*
* IMPORTS: ULONG hunk; hunk type
*
* RETURNS: NONE
*
* DESCRIPTION: calls the handler routine for the specified hunk type
*
***********************************************************************/
processhunk(hunk)
ULONG hunk;
{
switch (hunk)
{
case HUNK_HEADER:
header_hunk();
break;
case HUNK_CODE:
code_hunk();
break;
case HUNK_RELOC8:
case HUNK_RELOC16:
case HUNK_RELOC32:
reloc_hunk();
break;
case HUNK_DEBUG:
debug_hunk();
break;
case HUNK_END:
first++;
break;
case HUNK_DATA:
data_hunk();
break;
case HUNK_BSS:
bss_hunk();
break;
default :
break;
}
}
/***********************************************************************
*
* ROUTINE: fastforward
*
* IMPORTS: NONE
*
* RETURNS: NONE
*
* DESCRIPTION: advances <offset> long words through the file;
*
***********************************************************************/
fastforward(offset)
long offset;
{
ULONG readlong();
int oldpos, i;
offset *= sizeof(ULONG);
oldpos = Seek(fd, offset, OFFSET_CURRENT);
}
/***********************************************************************
*
* ROUTINE: fastback
*
* IMPORTS: NONE
*
* RETURNS: NONE
*
* DESCRIPTION: Backs up 1 long word in the file
*
***********************************************************************/
fastback()
{
int oldpos;
oldpos = Seek(fd, -sizeof(ULONG), OFFSET_CURRENT);
}
/***********************************************************************
*
* ROUTINE: header_hunk
*
* IMPORTS: none
*
* RETURNS: none
*
* DESCRIPTION: Processes the header hunk and allocates enough memory
* for the hunk table.
*
***********************************************************************/
header_hunk()
{
ULONG chars_in_name, size, readlong();
int oldposition, i;
long offset;
chars_in_name = readlong();
while (chars_in_name)
{
offset = chars_in_name;
fastforward(offset);
chars_in_name = readlong();
}
size = readlong();
first = readlong();
last = readlong();
offset = 0;
for (i = first; i <= last; i++)
{
offset += readlong();
}
changelist = (ULONG *)AllocMem(size * sizeof(ULONG), 0);
listsize = size;
current = 0;
}
/***********************************************************************
*
* ROUTINE: code_hunk
*
* IMPORTS: NONE
*
* RETURNS: NONE
*
* DESCRIPTION: processes all code hunks
*
***********************************************************************/
code_hunk()
{
ULONG size, temp, readlong();
changelist[current++] = codemem;
size = readlong();
fastforward(size);
}
/***********************************************************************
*
* ROUTINE: reloc_hunk
*
* IMPORTS: NONE
*
* RETURNS: NONE
*
* DESCRIPTION: handles all reloc32 hunks
*
***********************************************************************/
reloc_hunk()
{
ULONG num, garb, readlong();
int i;
num = readlong();
while (num != 0)
{
num++;
fastforward(num);
num = readlong();
}
}
/***********************************************************************
*
* ROUTINE: debug_hunk
*
* IMPORTS: NONE
*
* RETURNS: NONE
*
* DESCRIPTION: handles all debug hunks
*
***********************************************************************/
debug_hunk()
{
ULONG num, readlong();
num = readlong();
if (num >0)
{
fastforward(num);
}
}
/***********************************************************************
*
* ROUTINE: data_hunk
*
* IMPORTS: NONE
*
* RETURNS: NONE
*
* DESCRIPTION: processes all data hunks.
*
***********************************************************************/
data_hunk()
{
ULONG readlong();
long num, check_len;
BOOL test_string();
num = readlong();
changelist[current++] = datamem;
fastforward(num);
}
/***********************************************************************
*
* ROUTINE: bss_hunk
*
* IMPORTS: none
*
* RETURNS: none
*
* DESCRIPTION: handles all uninitiallized data hunks
*
***********************************************************************/
bss_hunk()
{
ULONG num, readlong();
changelist[current++] = bssmem;
num = readlong();
}
/***********************************************************************
*
* ROUTINE: newtype
*
* IMPORTS: ULONG type; type of memory hunk is to be loaded into
*
* RETURNS: NONE
*
* DESCRIPTION: Changes the specification for where a hunk is to be
* loaded into memory.
*
***********************************************************************/
newtype(type)
ULONG type;
{
ULONG readlong(), oldval, wrote, newval;
oldval = readlong();
if (type != SET_UNCHANGED)
{
fastback();
oldval &= SET_MASK;
newval = oldval | type;
if (verbose) {
printf("changing %x to %x\n", oldval, newval);
}
wrote = Write(fd, &newval, sizeof(ULONG));
if (wrote != sizeof(ULONG))
{
printf("did not write full hunk label\n");
Exit();
}
}
}
/***********************************************************************
*
* ROUTINE: Exit
*
* IMPORTS: NONE
*
* RETURNS: NONE
*
* DESCRIPTION: Frees memory, closes file, exits program.
*
***********************************************************************/
Exit()
{
int i;
if (changelist != NULL)
{
FreeMem(changelist, listsize);
changelist = NULL;
}
Close(fd);
exit(0);
}
/***********************************************************************
*
* ROUTINE: fixhunk
*
* IMPORTS: none
*
* RETURNS: none
*
* DESCRIPTION: read through the table of hunk definitions made by this
* program and calls newtype() for all hunks that have been
* changed
*
***********************************************************************/
fixhunk()
{
ULONG chars_in_name, size, readlong();
int oldposition, i;
long offset;
oldposition = Seek(fd, 4L, OFFSET_BEGINNING);
chars_in_name = readlong();
while (chars_in_name)
{
offset = chars_in_name;
fastforward(offset);
chars_in_name = readlong();
}
size = readlong();
size = readlong();
size = readlong();
for (i = 0; i < current; i++)
{
newtype(changelist[i]);
}
}
/***********************************************************************
*
* ROUTINE: set_mem_flags
*
* IMPORTS: char *arg; CLI argument to be interpreted
*
* RETURNS: none
*
* DESCRIPTION: interprets a hunk memory specification
*
***********************************************************************/
set_mem_flags(arg)
char *arg;
{
switch(arg[0])
{
case SPEC_DATA:
datamem = memtype(arg[2]);
break;
case SPEC_CODE:
codemem = memtype(arg[2]);
break;
case SPEC_BSS:
bssmem = memtype(arg[2]);
break;
}
}
/***********************************************************************
*
* ROUTINE: show_usage
*
* IMPORTS: char *name; program name
*
* RETURNS: none
*
* DESCRIPTION: shows usage for the program
*
***********************************************************************/
show_usage(name)
char *name;
{
printf("USAGE: %s <file> [-v] [c,d,b]=[c,f,e]\n", name);
printf("\n-v sets verbose mode on\n");
printf("[c/d/b] specify which hunks are to be altered.\n");
printf(" c - code, d - data, b - uninitaillized data.\n");
printf("[c/f/e] specify where the altered hunks are to load.\n");
printf(" c - chip, f - fast, e - doesn't matter\n");
printf("\nNote: changing two or more hunk types requires that the\n");
printf(" specification argument be repeated for each hunk\n");
printf(" type. ie to load code into fast memory, and data\n");
printf(" into chip memory, the command would be\n");
printf(" %s <file> c=f d=c\n", name);
printf("\nYou may distribute this program free of charge to anyone\n");
printf("as long as: the README file is distributed with it, and it\n");
printf("is not part of a commercial product.\n\n");
printf("If you use this program and it saves you several hours of\n");
printf("work, I would appreciate any contribution\n");
printf(" Terry Fisher, Jan 17 1988\n");
exit(0);
}